package com.ftw.commons.widgets.refresh

import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.util.DisplayMetrics
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.recyclerview.widget.LinearSmoothScroller
import com.ftw.commons.utils.ScreenUtils

/**
 * 描    述：
 * 作    者：fantianwen
 * 时    间：2019-08-21  11:15
 */
class WrapContentLinearLayoutManager(
    context: Context,
    orientation: Int,
    reverseLayout: Boolean
) : LinearLayoutManager(context, orientation, reverseLayout) {


    private val mMeasuredDimension = IntArray(2)
    private var recyclerHeight = 0
    private var mRecycler: RecyclerView.Recycler? = null
    private var listSlideHeight = 0//滑动距离


    override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) {
        try {
            this.mRecycler = recycler
            super.onLayoutChildren(recycler, state)
        } catch (e: IndexOutOfBoundsException) {
            Log.e("probe", "ERROR = " + e.message)
        }

    }


    /**
     * @param root             最外层布局
     * @param needToScrollView 要滚动的布局,就是说在键盘弹出的时候,你需要试图滚动上去的View,在键盘隐藏的时候,他又会滚动到原来的位置的布局
     */
    private fun controlKeyboardLayout(
        activity: Activity,
        root: View,
        needToScrollView: View,
        linearLayoutManager: WrapContentLinearLayoutManager?
    ) {
        val bottomStatusHeight = ScreenUtils.getNavigationBarHeight(activity)

        root.viewTreeObserver.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            private val r = Rect()
            override fun onGlobalLayout() {
                //获取当前界面可视部分
                activity.window.decorView.getWindowVisibleDisplayFrame(r)
                //获取屏幕的高度
                val screenHeight = activity.window.decorView.rootView.height
                //此处就是用来获取键盘的高度的， 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
                val heightDifference = screenHeight - r.bottom
                var recyclerHeight = 0
                if (linearLayoutManager != null) {
                    recyclerHeight = linearLayoutManager.getRecyclerHeight()
                }
                if (heightDifference == 0 || heightDifference == bottomStatusHeight) {
                    needToScrollView.scrollTo(0, 0)
                } else {
                    if (heightDifference < recyclerHeight) {
                        val contentHeight =
                            if (linearLayoutManager == null) 0 else linearLayoutManager.getHeight()
                        if (recyclerHeight < contentHeight) {
                            listSlideHeight = heightDifference - (contentHeight - recyclerHeight)
                            needToScrollView.scrollTo(0, listSlideHeight)
                        } else {
                            listSlideHeight = heightDifference
                            needToScrollView.scrollTo(0, listSlideHeight)
                        }
                    } else {
                        listSlideHeight = 0
                    }
                }
            }
        })
    }

    fun getRecyclerHeight(): Int {

        mRecycler?.let {
            var height = 0
            for (i in 0 until itemCount) {
                measureScrapChild(
                    mRecycler!!,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension
                )

                if (orientation == HORIZONTAL) {
                    if (i == 0) {
                        height = mMeasuredDimension[1]
                    }
                } else {
                    height += mMeasuredDimension[1]
                }
            }
            recyclerHeight = height
            return recyclerHeight
        } ?: let { return 0 }
    }

    private fun measureScrapChild(
        recycler: RecyclerView.Recycler, widthSpec: Int,
        heightSpec: Int, measuredDimension: IntArray
    ) {
        try {
            //fix 动态添加时报IndexOutOfBoundsException
            val view = recycler.getViewForPosition(0)
            view?.let {
                val p = view.layoutParams as RecyclerView.LayoutParams

                val childWidthSpec = ViewGroup.getChildMeasureSpec(
                    widthSpec,
                    paddingLeft + paddingRight, p.width
                )

                val childHeightSpec = ViewGroup.getChildMeasureSpec(
                    heightSpec,
                    paddingTop + paddingBottom, p.height
                )

                view.measure(childWidthSpec, childHeightSpec)
                measuredDimension[0] = view.measuredWidth + p.leftMargin + p.rightMargin
                measuredDimension[1] = view.measuredHeight + p.bottomMargin + p.topMargin
                recycler.recycleView(view)
            }

        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
        }
    }

    override fun smoothScrollToPosition(
        recyclerView: RecyclerView?,
        state: RecyclerView.State?,
        position: Int
    ) {
        val smoothScroller = object : LinearSmoothScroller(recyclerView!!.context) {
            override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
                return 150f / displayMetrics!!.density
            }
        }
        smoothScroller.targetPosition = position
        startSmoothScroll(smoothScroller)
    }
}